//
// Created by Kevin on 2025/1/10.
//
#include <jni.h>
#include <dlfcn.h>
#include <android/log.h>
#include <mutex>
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <unistd.h>
#include <queue>
#include <thread>
#include <dirent.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>


extern "C"
{
#include "libavutil/imgutils.h"
#include "libavdevice/avdevice.h"
#include "libswscale/swscale.h"
#include "libavutil/log.h"
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libavutil/opt.h"
#include "libavutil/avutil.h"
#include "libavutil/bprint.h"
//#include "libavutil/error.h"
}
//#pragma comment(lib,"avcodec.lib")

// 定义日志标记
#define LOG_TAG "NativeFFmpeg"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
// 导入ffmpeg的main符号,直接jni或者ffi调用也行，但是需要解决一个问题：ffmpeg内部会调用exit退出进程，在安卓会导致Activity退出。
//目前本文件的解决方案是在exit过程中抛出c++异常并捕获，中断后续退出操作。
extern "C" int main(int argc, char **argv);

static std::vector<std::string> split(const std::string &str, char delim);

static std::vector<std::string> parseArgv(const std::string &str);

static bool _isFFmpegInit = false;
static std::mutex _mtx;

static bool _isCallBackTmp = false;
// 调用ffmpeg命令行，参数是命令行,例如：ffmpeg --version
extern "C" int ffmpeg_exec(char *shell) {
    if (!_isFFmpegInit) {
        std::unique_lock<std::mutex> lck(_mtx);
        if (!_isFFmpegInit) {
            // 自定义日志回调
            av_log_set_callback([](void *avcl, int level, const char *fmt, va_list vl) {
                if (level >= 0)
                    level &= 0xff;
                if (level > av_log_get_level())
                    return;
                AVBPrint part;
                av_bprint_init(&part, 0, 65536);
                av_vbprintf(&part, fmt, vl);
                __android_log_print(ANDROID_LOG_INFO, "ffmpeg", "%s", part.str);
                if (part.len > 0) {
                    av_bprint_finalize(&part, nullptr);
                }
            });

            // 取消 `atexit([]() { throw 0; })`，防止异常终止
            atexit([]() {
                __android_log_print(ANDROID_LOG_ERROR, "ffmpeg", "Process exiting...");
            });

            _isFFmpegInit = true;
        }
    }

    try {
        // 解析命令行
        auto strArgv = parseArgv(shell);
        std::vector<char *> argv;
        for (int i = 0; i < strArgv.size(); i++) {
            argv.push_back((char *) strArgv[i].c_str());
        }

        // 调用 FFmpeg 的 main
        int result = main(argv.size(), argv.data());
        __android_log_print(ANDROID_LOG_INFO, "ffmpeg", "ffmpeg main returned: %d", result);
        return result;
    } catch (const std::exception &e) {
        __android_log_print(ANDROID_LOG_ERROR, "ffmpeg", "Exception in ffmpeg_exec: %s", e.what());
    } catch (...) {
        __android_log_print(ANDROID_LOG_ERROR, "ffmpeg", "Unknown exception in ffmpeg_exec");
    }

    return -1;
}


static std::vector<std::string> split(const std::string &str, char delim) {
    std::vector<std::string> tokens;
    std::istringstream iss(str);
    std::string token;
    while (std::getline(iss, token, delim))
        if (!token.empty())
            tokens.push_back(token);
    return tokens;
}

static std::vector<std::string> parseArgv(const std::string &str) {
    std::vector<std::string> args;
    int n = 0;
    for (auto i: split(str, '"')) {
        if (n++ % 2 == 0)
            for (auto j: split(i, ' '))
                args.push_back(j);
        else
            args.push_back(i);
    }
    return args;
}


extern "C"
JNIEXPORT jint JNICALL
Java_com_vmark_ffmpeglib_Ffmpeg_ffmpeg_1exec(JNIEnv *env, jobject thiz, jstring command) {
    const char *cmd = env->GetStringUTFChars(command, nullptr);
    jint result = ffmpeg_exec((char *) cmd);
    env->ReleaseStringUTFChars(command, cmd);
    return result;
}


//---------------------------------------------

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>

// 推流参数配置
#define OUTPUT_URL "rtmp://127.0.0.1:1935/live/android"
#define FRAME_RATE 25
#define BIT_RATE 2000000
#define GOP_SIZE 30

// 全局上下文
AVFormatContext *ofmt_ctx = nullptr;
AVCodecContext *enc_ctx = nullptr;
SwsContext *sws_ctx = nullptr;
AVStream *out_stream = nullptr;
int64_t pts_counter = 0;

#define YUV422_WIDTH 640
#define YUV422_HEIGHT 512
#define Y16_WIDTH 640
#define Y16_HEIGHT 512

//------推流----------
std::queue<unsigned char *> frameQueue;
std::mutex queueMutex;
std::condition_variable mcv;  // 用于队列为空时休眠线程
//------推流----------



//----取温---
// 共享变量，用于存储Y16数据
std::vector<unsigned char> sharedY16Data;
std::mutex y16DataMutex; // 用于保护 sharedY16Data
//----取温---


// 获取当前帧并提取温度
float getTemperature(int x, int y) {
    std::lock_guard<std::mutex> lock(y16DataMutex); // 确保线程安全
    if (!sharedY16Data.empty()) {
        // 访问 sharedY16Data 数据
        LOGI("访问 Y16 数据，共享数据大小: %zu", sharedY16Data.size());
        // 进行相关处理
        long temp_index = (y * Y16_WIDTH * 2) + (2 * x);
        uint16_t temp_value = (sharedY16Data[temp_index + 1] << 8) | sharedY16Data[temp_index];
        return (float) temp_value / 128.0f;
    }

    return -999.99f;
}


// 初始化推流环境
int init_streamer() {
    avdevice_register_all();
    av_log_set_level(AV_LOG_DEBUG);
    avformat_network_init();

    // 创建输出上下文
    avformat_alloc_output_context2(&ofmt_ctx, nullptr, "flv", OUTPUT_URL);
    if (!ofmt_ctx) return -1;

    // 查找编码器
    AVCodec *encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
    if (!encoder) return -1;

    // 创建编码器上下文
    enc_ctx = avcodec_alloc_context3(encoder);
    enc_ctx->width = 640;
    enc_ctx->height = 512;
    enc_ctx->time_base = (AVRational) {1, FRAME_RATE};
    enc_ctx->framerate = (AVRational) {FRAME_RATE, 1};
    enc_ctx->pix_fmt = AV_PIX_FMT_YUV420P; // 目标格式
    enc_ctx->bit_rate = BIT_RATE;
    enc_ctx->gop_size = GOP_SIZE;

    // 设置H264参数
    av_opt_set(enc_ctx->priv_data, "preset", "ultrafast", 0);
    av_opt_set(enc_ctx->priv_data, "tune", "zerolatency", 0);

    if (avcodec_open2(enc_ctx, encoder, nullptr) < 0) return -1;

    // 创建输出流
    out_stream = avformat_new_stream(ofmt_ctx, encoder);
    avcodec_parameters_from_context(out_stream->codecpar, enc_ctx);

    // 初始化格式转换上下文（YUV422 -> YUV420P）
    sws_ctx = sws_getContext(enc_ctx->width, enc_ctx->height,
                             AV_PIX_FMT_YUYV422,  // 输入格式
                             enc_ctx->width, enc_ctx->height,
                             enc_ctx->pix_fmt,
                             SWS_BILINEAR, nullptr, nullptr, nullptr);

    // 打开输出IO
    if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) {
        if (avio_open(&ofmt_ctx->pb, OUTPUT_URL, AVIO_FLAG_WRITE) < 0) return -1;
    }

    // 写文件头
    return avformat_write_header(ofmt_ctx, nullptr);
}

// 推送单帧数据
int push_frame(uint8_t *yuv_data, size_t data_size) {
    // 预先分配和复用 AVFrame
    static AVFrame *frame = av_frame_alloc();
    static AVFrame *conv_frame = av_frame_alloc();

    if (!frame || !conv_frame) {
        return AVERROR(ENOMEM); // 内存分配失败
    }

    // 初始化原始数据帧
    frame->width = enc_ctx->width;
    frame->height = enc_ctx->height;
    frame->format = AV_PIX_FMT_YUYV422;

    // 填充原始数据（假设数据布局符合FFmpeg要求）
    av_image_fill_arrays(frame->data, frame->linesize, yuv_data,
                         AV_PIX_FMT_YUYV422, frame->width, frame->height, 1);

    // 初始化转换帧，如果需要，可以跳过反复分配
    if (!conv_frame->data[0]) {
        conv_frame->format = enc_ctx->pix_fmt;
        conv_frame->width = enc_ctx->width;
        conv_frame->height = enc_ctx->height;
        if (av_frame_get_buffer(conv_frame, 0) < 0) {
            return AVERROR(ENOMEM); // 缓冲区分配失败
        }
    }

    // 转换像素格式
    sws_scale(sws_ctx, (const uint8_t **) frame->data, frame->linesize,
              0, enc_ctx->height, conv_frame->data, conv_frame->linesize);

    // 设置时间戳
    conv_frame->pts = pts_counter++;

    // 发送帧到编码器
    int ret = avcodec_send_frame(enc_ctx, conv_frame);
    if (ret < 0) {
        return ret; // 错误代码
    }

    // 接收编码后的包并写入文件
    AVPacket pkt;
    av_init_packet(&pkt);
    while (1) {
        ret = avcodec_receive_packet(enc_ctx, &pkt);
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
            break; // 等待下一帧
        }
        if (ret < 0) {
            return ret; // 错误代码
        }

        // 设置流索引和时间基
        pkt.stream_index = out_stream->index;
        av_packet_rescale_ts(&pkt, enc_ctx->time_base, out_stream->time_base);

        // 写入数据包
        ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
        if (ret < 0) {
            av_packet_unref(&pkt);
            return ret; // 写入失败
        }

        av_packet_unref(&pkt);
    }

    return 0;
}

// 释放资源
void cleanup_streamer() {
    LOGI("===释放资源===");
    // 刷新编码器
    avcodec_send_frame(enc_ctx, nullptr);
    AVPacket pkt;
    av_init_packet(&pkt);
    while (avcodec_receive_packet(enc_ctx, &pkt) == 0) {
        av_interleaved_write_frame(ofmt_ctx, &pkt);
        av_packet_unref(&pkt);
    }

    // 写文件尾
    av_write_trailer(ofmt_ctx);

    // 释放资源
    if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
        avio_closep(&ofmt_ctx->pb);

    sws_freeContext(sws_ctx);
    avcodec_free_context(&enc_ctx);
    avformat_free_context(ofmt_ctx);
}

// 提取 YUV422 和  Y16
void
extractYUV422AndY16(unsigned char *rawData, unsigned char *yuv422Data, unsigned char *y16Data) {
    int i;
    for (i = 0; i < YUV422_HEIGHT; i++) {
        //Y0 U0 Y1 V0
        memcpy(yuv422Data + (i * YUV422_WIDTH * 2), rawData + (i * (YUV422_WIDTH + Y16_WIDTH) * 2),
               YUV422_WIDTH * 2);
        //Y0 Y0 Y1 Y1
        memcpy(y16Data + (i * Y16_WIDTH * 2),
               rawData + ((i * (YUV422_WIDTH + Y16_WIDTH) * 2) + (YUV422_WIDTH * 2)),
               Y16_WIDTH * 2);
    }
}

void
extractYUV422AndY16Two(const jbyte *rawData, unsigned char *yuv422Data, unsigned char *y16Data) {
    int i;
    for (i = 0; i < YUV422_HEIGHT; i++) {
        //Y0 U0 Y1 V0
        memcpy(yuv422Data + (i * YUV422_WIDTH * 2), rawData + (i * (YUV422_WIDTH + Y16_WIDTH) * 2),
               YUV422_WIDTH * 2);
        //Y0 Y0 Y1 Y1
        memcpy(y16Data + (i * Y16_WIDTH * 2),
               rawData + ((i * (YUV422_WIDTH + Y16_WIDTH) * 2) + (YUV422_WIDTH * 2)),
               Y16_WIDTH * 2);
    }
}


//从队列中提取 YUV422 推流并消费
void pushStream() {
    while (true) {
        unsigned char *yuv422Data = nullptr;
        // 等待队列中的数据，或者在队列为空时休眠
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            //如果队列为空，则等待，直到有数据加入队列
            mcv.wait(lock, [] { return !frameQueue.empty(); });
            LOGI("处理队列帧数====: frameQueue.size====%d", frameQueue.size());
            // 从队列中取出数据
            yuv422Data = frameQueue.front();
            frameQueue.pop();
        }

        if (yuv422Data != nullptr) {
            // 从摄像头获取YUV422数据（假设数据指针为yuv_buffer）
            if (push_frame(yuv422Data, 640 * 512) < 0) {
                // 处理推流错误
                LOGI("========处理推流错误=======");
            }
            // 如果frameQueue中的数据是由其他地方分配的，需要确保正确释放
            free(yuv422Data);  // 释放内存，确保不会内存泄漏
        }
    }

}

//打开usb 摄像头  并且获取数据
void getUsbData() {
    /* while (true) { // 外层循环实现持续重连
         struct dirent *entry;
         DIR *dir = opendir("/dev");

         if (dir == nullptr) {
             LOGI("无法打开 /dev 目录");
             return;
         }

         bool device_opened = false;
         while ((entry = readdir(dir)) != nullptr) {
             if (strncmp(entry->d_name, "video", 5) == 0) {
                 char devicePath[256];
                 snprintf(devicePath, sizeof(devicePath), "/dev/%s", entry->d_name);

                 AVFormatContext *formatContext = nullptr;
                 const AVInputFormat *inputFormat = av_find_input_format("v4l2");
                 int res = avformat_open_input(&formatContext, devicePath, inputFormat, nullptr);
                 if (res != 0) {
                     LOGI("打开设备失败: %s, 错误码: %d", devicePath, res);
                     avformat_close_input(&formatContext);
                     continue;
                 }

                 // 查找视频流
                 int videoStreamIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_VIDEO, -1,
                                                            -1, nullptr, 0);
                 if (videoStreamIndex < 0) {
                     LOGI("未找到视频流");
                     avformat_close_input(&formatContext);
                     continue;
                 }

                 LOGI("成功打开设备，开始读取数据...");
                 device_opened = true;

                 AVPacket packet;
                 while (true) { // 内层循环持续读取数据
                     int ret = av_read_frame(formatContext, &packet);
                     if (ret < 0) {
                         LOGI("读取数据失败，错误码: %d，尝试重连...", ret);
                         break; // 跳出内层循环，重新扫描设备
                     }

                     if (packet.stream_index == videoStreamIndex) {
                         if (packet.size == 1310720) {
                             // 从摄像头获取YUV422数据（假设数据指针为yuv_buffer）
 //                        auto *yuv422Data = (unsigned char *) malloc(
 //                                YUV422_WIDTH * YUV422_HEIGHT * 2);
 //                        auto *y16Data = (unsigned char *) malloc(Y16_WIDTH * Y16_HEIGHT * 2);

 //                        extractYUV422AndY16(packet.data, yuv422Data, y16Data);
 //
 //                        // 将 YUV422 数据放入队列
 ////                        if (index == 0) {
 ////                            index = 0;
 //                        {
 //                            std::lock_guard<std::mutex> lock(queueMutex);
 //                            if (frameQueue.size() >= 100) {
 //                                auto oldFrame = frameQueue.front();
 //                                frameQueue.pop(); // 丢弃旧帧
 //                            }
 //                            frameQueue.push(yuv422Data);  // 将数据推送到队列中
 //                            mcv.notify_one();  // 通知等待中的线程
 //                        }
 ////                        } else {
 ////                            index++;
 ////                            free(yuv422Data);
 ////                        }
 //
 //                        // 将 Y16 温度数据 放入 公共变量
 //
 //                        //free(yuv422Data);
 //
 //
 //                        {
 //                            std::lock_guard<std::mutex> lock(y16DataMutex); // 加锁
 //                            sharedY16Data.assign(y16Data,
 //                                                 y16Data +
 //                                                 (Y16_WIDTH * Y16_HEIGHT * 2)); // 将 Y16 数据存入公共变量
 //                            //LOGI("Y16 数据已更新");
 //                        }
 //                        free(yuv422Data);
 //                        // 释放 Y16 数据
 //                        free(y16Data);
                         }

                     }
                     av_packet_unref(&packet);
                 }

                 avformat_close_input(&formatContext);
                 formatContext = nullptr; // 显式置空防止野指针
                 cleanup_streamer();      // 清理可能存在的残留资源
                 break; // 跳出设备扫描循环，重新开始
             }
         }
         closedir(dir);
     }*/

    struct dirent *entry;
    DIR *dir = opendir("/dev");

    if (dir == nullptr) {
        LOGI("无法打开 /dev 目录");
        return;
    }

    bool device_opened = false;
    while ((entry = readdir(dir)) != nullptr) {
        // 判断设备是否是视频设备
        LOGI("namexxx==========%s", entry->d_name);
        if (strncmp(entry->d_name, "video", 5) == 0) {

            char devicePath[256];
            snprintf(devicePath, sizeof(devicePath), "/dev/%s", entry->d_name);

            LOGI("path======%s", devicePath);
            //
            AVFormatContext *formatContext = nullptr;

//            //注册 FFmpeg 设备库
            avdevice_register_all();
            av_log_set_level(AV_LOG_DEBUG);
//            //定义格式
            const AVInputFormat *inputFormat = av_find_input_format("v4l2"); // 用于 USB 摄像头
//            const AVInputFormat *inputFormat = av_find_input_format("avfoundation"); // 用于 USB 摄像头
            //打开 USB 摄像头
//            AVDictionary *options = nullptr;
//            av_dict_set(&options, "buffer_size", "8388608", 0);  // 设置缓冲区为 8MB
//            av_dict_set(&options, "video_size", "1920x1080", 0);  // 设置视频分辨率
//            av_dict_set(&options, "video_size", "1280x512", 0);  // 设置视频分辨率
//            av_dict_set(&options, "framerate", "15", 0);  // 设置帧率
//              av_dict_set(&options, "verbose", "1", 0);
//            av_dict_set(&options, "pix_fmt", "rgba", 0);
            int res = avformat_open_input(&formatContext, devicePath, inputFormat, nullptr);
            if (res != 0) {
                LOGI("%d  打不开对应地址设备 %s", res, devicePath);
                avformat_close_input(&formatContext);
                continue;
                return;
            }
            //检索流通道
            int videoStreamIndex = -1;
            for (int i = 0; i < formatContext->nb_streams; i++) {
                //是否视频流
                if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
                    videoStreamIndex = i;
                    break;
                }
            }

            if (videoStreamIndex == -1) {
                LOGI("找不到视频流");
                avformat_close_input(&formatContext);
                continue;
            } else {
                LOGI("视频流videoStreamIndex=%d", videoStreamIndex);
            }

            //获取视频流编解码方式
            AVCodecParameters *codecParams = formatContext->streams[videoStreamIndex]->codecpar;
            LOGI("===Video Codec: %s", avcodec_get_name(codecParams->codec_id));
            LOGI("===Video Width: %d", codecParams->width);
            LOGI("===Video Height: %d", codecParams->height);
            LOGI("===Video Bit_rate: %d", codecParams->bit_rate);
            LOGI("===Video level: %d", codecParams->level);

            AVPacket packet;
            int index = 0;

            if (init_streamer() < 0) {
                // 处理初始化失败
                LOGI("========处理初始化失败=======");
            }
            LOGI("================33333333===============");
            while (true) {
                int ret = av_read_frame(formatContext, &packet);
                if (ret < 0) {
                    LOGI("读取数据失败，错误码: %d，尝试重连...", ret);
                    break; // 跳出内层循环，重新扫描设备
                }
                LOGI("=================xxxxxxxxxxxx=================");
                LOGI("原始数据====:packetDts=%lld,packetSize=%d",
                     packet.dts, packet.size);
                if (packet.stream_index == videoStreamIndex) {
                    if (packet.size == 1310720) {
                        // 从摄像头获取YUV422数据（假设数据指针为yuv_buffer）
//                        auto *yuv422Data = (unsigned char *) malloc(
//                                YUV422_WIDTH * YUV422_HEIGHT * 2);
//                        auto *y16Data = (unsigned char *) malloc(Y16_WIDTH * Y16_HEIGHT * 2);

//                        extractYUV422AndY16(packet.data, yuv422Data, y16Data);
//
//                        // 将 YUV422 数据放入队列
////                        if (index == 0) {
////                            index = 0;
//                        {
//                            std::lock_guard<std::mutex> lock(queueMutex);
//                            if (frameQueue.size() >= 100) {
//                                auto oldFrame = frameQueue.front();
//                                frameQueue.pop(); // 丢弃旧帧
//                            }
//                            frameQueue.push(yuv422Data);  // 将数据推送到队列中
//                            mcv.notify_one();  // 通知等待中的线程
//                        }
////                        } else {
////                            index++;
////                            free(yuv422Data);
////                        }
//
//                        // 将 Y16 温度数据 放入 公共变量
//
//                        //free(yuv422Data);
//
//
//                        {
//                            std::lock_guard<std::mutex> lock(y16DataMutex); // 加锁
//                            sharedY16Data.assign(y16Data,
//                                                 y16Data +
//                                                 (Y16_WIDTH * Y16_HEIGHT * 2)); // 将 Y16 数据存入公共变量
//                            //LOGI("Y16 数据已更新");
//                        }
//                        free(yuv422Data);
//                        // 释放 Y16 数据
//                        free(y16Data);
                    }

                }
                av_packet_unref(&packet);
            }
            LOGI("====================结束，没有==========");
            // Cleanup
            avformat_close_input(&formatContext);

            cleanup_streamer();
            break;
        }
    }
    closedir(dir);
}
//--------------------------------------------

extern "C"
JNIEXPORT void JNICALL
Java_com_vmark_ffmpeglib_Ffmpeg_usbCamera(JNIEnv *env, jobject thiz, jstring device_path) {
    getUsbData();

}

extern "C"
JNIEXPORT void JNICALL
Java_com_vmark_ffmpeglib_Ffmpeg_pushStream__(JNIEnv *env, jobject thiz) {
    pushStream();
}

extern "C"
JNIEXPORT jfloat JNICALL
Java_com_vmark_ffmpeglib_Ffmpeg_getTemperatureFromFrame(JNIEnv *env, jobject thiz, jint x, jint y) {
    return getTemperature(x, y);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_vmark_ffmpeglib_Ffmpeg_pushStreamData(JNIEnv *env, jobject thiz,  jobject buffer) {
    // 获取 ByteArray 数据
    unsigned char *byteArray = static_cast<unsigned char *>(env->GetDirectBufferAddress(buffer));
    if (byteArray == nullptr) {
        // 处理错误
        return;
    }
    jlong length = env->GetDirectBufferCapacity(buffer);

    auto *yuv422Data = (unsigned char *) malloc(
            YUV422_WIDTH * YUV422_HEIGHT * 2);
    auto *y16Data = (unsigned char *) malloc(Y16_WIDTH * Y16_HEIGHT * 2);

    if (yuv422Data == nullptr || y16Data == nullptr) {
        free(yuv422Data);
        free(y16Data);
        return;
    }

    extractYUV422AndY16Two(reinterpret_cast<const jbyte *>(byteArray), yuv422Data, y16Data);


    {
        std::lock_guard<std::mutex> lock(queueMutex);
        if (frameQueue.size() >= 100) {
            auto oldFrame = frameQueue.front();
            frameQueue.pop(); // 丢弃旧帧
        }

        frameQueue.push(yuv422Data);  // 将数据推送到队列中
        mcv.notify_one();  // 通知等待中的线程
    }

    {

        std::lock_guard<std::mutex> lock(y16DataMutex); // 加锁
        sharedY16Data.assign(y16Data,
                             y16Data +
                             (Y16_WIDTH * Y16_HEIGHT * 2)); // 将 Y16 数据存入公共变量
        //LOGI("Y16 数据已更新");
    }12
    // 释放 Y16 数据
    free(y16Data);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_vmark_ffmpeglib_Ffmpeg_cleanupStreamer(JNIEnv *env, jobject thiz) {
    cleanup_streamer();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_vmark_ffmpeglib_Ffmpeg_initUpStreamer(JNIEnv *env, jobject thiz) {
    init_streamer();
}